package com.carp.scaffolding.chain.processor;

import com.carp.scaffolding.config.MyFreeMarkerConfig;
import com.carp.scaffolding.config.prop.ProjectProperties;
import com.carp.scaffolding.container.TemplateContainer;
import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.file.Files;

/**
 * @author lile
 * @since 2023/2/28
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SpringBootProcessor extends Processor {
    private final MyFreeMarkerConfig configuration;
    private final ProjectProperties projectProperties;
    private final TemplateContainer templateContainer;

    @Override
    public void process() {
        log.info("开始生成 Spring Boot 项目代码...");
        templateContainer.getContainer().forEach(this::generate);
        log.info("Spring Boot 项目代码生成完毕");
        processNext();
    }

    public void generate(String dir) {
        File file = getFile(dir);

        if (!file.exists()) {
            if (!file.getParentFile().exists()) {
                boolean isSuccessful = file.getParentFile().mkdirs();
                Assert.isTrue(isSuccessful, "Failed to make directory.");
            }
        }

        try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(Files.newOutputStream(file.toPath()))) {
            configuration.getConfiguration().getTemplate(dir).process(projectProperties, outputStreamWriter);
        } catch (IOException | TemplateException e) {
            throw new RuntimeException(e);
        }
    }

    private File getFile(String dir) {
        String filePath = System.getProperty("user.dir") + "/output/" + projectProperties.getName() + dir.replace(".ftl", "");
        if (dir.contains("Application.java.ftl") || dir.contains("ApplicationTests.java.ftl")) {
            filePath = filePath.replace("Application", projectProperties.getApplicationName());
        }
        return new File(filePath);
    }

}
